let path = require("path");
let HtmlWebpackPlugin = require('html-webpack-plugin');
let MiniCssExtractPlugin = require('mini-css-extract-plugin');//抽离css样式
let OptimizeCss = require('optimize-css-assets-webpack-plugin');//css压缩插件
let UglifyJsPlugin = require('uglifyjs-webpack-plugin'); //js压缩插件
let CleanWebpackPlugin = require('clean-webpack-plugin');// 每次打包，使build文件夹先被清空，在生成
let webpack = require('webpack');
// file-loader 默认会在内部生成一张图片，到build目录下，并把生成的图片名字返回回来
// urll-loader 具有file-loader的功能，另外还可以配置，将小的照片直接转为base64来减少请求
// html-withimg-loader  在元素中引用图片<img src="a.png"> 打包到build后依然是a.png就会找不到图片，用这个loder就能就进行转换
module.exports = {
    optimization:{ //优化项
        minimizer:[
            new UglifyJsPlugin({
                cache:true, // 是否适用缓存
                parallel: true,// 是否并发打包
                sourceMap: true // es6转es5 的源码映射
            }),//js压缩,开启优化项后，production模式下默认的js压缩会失效
            new OptimizeCss()//css压缩
        ],
        splitChunks:{
                cacheGroups:{
                    common:{
                        chunks:'initial',
                        minSize:0,
                        minChunks:2,
                    },
                    vender:{
                        priority:1,// 权重，先抽离第三方，在抽离自己写的代码
                        test:/node_modules/,
                        chunks:'initial',
                        minSize:0, //大于多少字节时重用才被抽离
                        minChunks:2 //重复使用两次的代码就抽离出来
                    }
                }
            }
    },
    
    devServer:{ //开发服务器的配置
        hot: true, //开启热更新
        port: 3000,
        progress: true, 
        contentBase:"./build" 
    },
    mode: 'production', //模式 默认两种 production  development
    //entry: './src/index.js',
      entry:{
        index:'./src/index.js',
        other:'./src/other.js'
      },
    // 源码映射 会单独生成一个sourcemap文件 出错了会标识列和行
    //devtool:'source-map', //增加映射文件，可以帮助我们调试代码,会单独生成一个sourcemap文件，出错了会标识当前报错的行和列
    /* 
        devtool的其他几个值：'eval-source-map' 不会产生单独的文件，但是可以显示行和列
                            'cheap-module-source-map' 不会产生列，但是是一个单独的映射文件
                            'cheap-module-eval-source-map' 不会产生文件，集成在打包后的文件中，不会产生列
    */
   watch: true, // 开启监听，时时打包
   watchOptions:{ //监控的选项
     poll:1000, //每秒询问1000次，是不是有新内容要打包
     aggregateTimeout: 500, //单位是毫秒 防抖 一直输入代码的情况下不打包
     ignored: /node_modules/  //不需要进行监控
   },
    output:{
        //filename: 'bundle.[hash:8].js', //hash:8 表示只显示8位hash值
        filename:'[name].js',
        path: path.resolve(__dirname,'build'), //路径必须是绝对路径
     //   publicPath: 'http://sjf.com' //添加绝对路径
    },
    plugins:[
        new webpack.DefinePlugin({
            DEV:JSON.stringify('production'),//  webpack自带插件，定义全局变量
            COUNT: '1+1',// 会显示2  如果要显示1+1 则要JSON.stringify('1+1)
        }),
        new HtmlWebpackPlugin({
            template: './src/index.html',
            filename: 'index.html',
            hash: true, //增加hash值
            minify:{
                removeAttributeQuotes: true, //删除html元素属性的双引号
                collapseWhitespace: true, //去除空格，变为一行显示
                
            }
        }),
        new MiniCssExtractPlugin({
            filename: 'css/main.css'//抽离出来的css文件名 可以指定到某目录
        }),
        //new CleanWebpackPlugin(['./build']), // 如果有多个文件夹，就以数组的形式填写
        new webpack.BannerPlugin("版权声明内容"),  //webpack 自带插件  插入版权声明内容
        new webpack.NamedModulesPlugin(),//打印热更新的模块路径
        new webpack.HotModuleReplacementPlugin() // 热更新插件
    ],
    module:{
        noParse:/jquery/, //不去解析jQuery中的依赖库(明确知道该包不依赖其他库时可以加，加快打包速度)
        rules:[ //规则 先右后左，先下后上
            {
                test:/\.html$/,
                use:'html-withimg-loader'
            },
            {
                test:/\.(png|jpg|gif)$/,
               // use: 'file-loader'
                use:{
                    loader: 'url-loader',
                    options:{
                        limit:5*1024 ,//小于200k 就打包成base64（base64比原文件大三分之一左右）
                        outputPath: 'img/' //输出到哪里去
                    }
                }
            },
            {test:/\.css$/, use:[
                // {
                //     loader: 'style-loader', //把css插入到head标签中
                //     options:{
                //         insertAt:'top' //插入的位置，默认是放在head的最底下，改为top后就放上面了，可以写自己的样式
                //     }
                // },
                MiniCssExtractPlugin.loader, //理由插件将css抽离成单独的文件
                'css-loader', //解析 类似@import语法
                'postcss-loader',//自动添加样式前缀，需要增加一个postcss.config配置文件
            ]},
            {test:/\.less$/, use:[
                // {
                //     loader: 'style-loader', //把css插入到head标签中
                //     options:{
                //         insertAt:'top' //插入的位置，默认是放在head的最底下，改为top后就放上面了，可以写自己的样式
                //     }
                // },
                MiniCssExtractPlugin.loader,
                'css-loader', //解析 类似@import语法
                'less-loader',
                'postcss-loader',//自动添加样式前缀
            ]},
            {
                test:/\.js$/,
                use:{
                    loader:'babel-loader',
                    options:{
                        presets:[
                            '@babel/preset-env'
                        ],
                        plugins:[
                            ['@babel/plugin-proposal-class-properties'], // 转换class等es7语法
                            ['@babel/plugin-syntax-dynamic-import']
                        ]
                    }
                },
                include:path.resolve(__dirname,'src'),//只找src目录里的js
                exclude: /node_modules/  //排除该目录
            }
        ]
    }
}